# Create your models here.
import uuid
from enum import Enum, auto, unique

from datetime import datetime, date
from typing import Type

from django.db import models, transaction
from jqgame.basegame import GameType
from juqiadmin.common.utlis import get_web_settings_statistical_exclude_user_uuid_list

from wxcloudrun.models import BaseModel
from wxuser.models import (
    Users,
    UserScoreRecord,
    UserHunJingRecord,
    UserStoredMoneyRecord,
)


# Create your models here.
# user models
class JuqiAdmin(BaseModel):
    # real name auth
    user = models.CharField(max_length=30)
    password = models.CharField(max_length=30)

    class Meta:
        db_table = "JuqiAdmin"  # 数据库表名
        indexes = [
            models.Index(fields=["user"]),
        ]


# used by django : only exec once when app ready
def init_admin(user=None):
    user = user or "admin"
    if not JuqiAdmin.objects.filter(user=user).exists():
        JuqiAdmin(user=user, password="admin123").save()
    admin = JuqiAdmin.objects.get(user=user)
    return admin


@unique
class FinanceType(Enum):
    game = 1  # 游戏
    wxuser = 2  # 微信用户


@unique
class FinanceStatus(models.IntegerChoices):
    # 用户身份
    user = 0  # 用户
    proxy = 1  # 代理


@unique
class FinanceRechargeRaffleCostType(models.IntegerChoices):
    none = 0
    hunjing = 1  # 魂晶
    score = 2  # 积分


class Finance(BaseModel):
    user_uuid = models.UUIDField(null=True, default=None)

    finance_status = models.PositiveIntegerField(
        default=FinanceStatus.user,
        choices=FinanceStatus.choices,
    )

    # 汇总数据类型
    finance_type = models.PositiveIntegerField(default=0)

    raffle_cost_type = models.PositiveIntegerField(
        choices=FinanceRechargeRaffleCostType.choices,
        default=FinanceRechargeRaffleCostType.none,
    )

    game_type = models.PositiveIntegerField(default=0)

    game_uuid = models.UUIDField(null=True, default=None)

    # 总充值
    all_recharge = models.IntegerField(default=0)

    # 后台充值
    all_admin_recharge = models.IntegerField(default=0)

    # 总提现
    all_withdraw = models.IntegerField(default=0)

    # 所有抽奖收入, 单次抽奖
    all_raffle_income = models.IntegerField(default=0)

    # 所有奖品成本
    all_raffle_cost = models.IntegerField(default=0)

    # 所有抽奖利润
    all_raffle_profit = models.IntegerField(default=0)

    all_delivery_amount = models.IntegerField(default=0)

    class Meta:
        db_table = "Finance"  # 数据库表名
        indexes = [
            models.Index(fields=["uuid"]),
            models.Index(fields=["deleted"]),
            models.Index(fields=["user_uuid"]),
            models.Index(fields=["finance_type"]),
        ]


def update_finnce_profit(fin: Finance):
    # used after update income and cost
    fin.all_raffle_profit = fin.all_raffle_income - fin.all_raffle_cost
    return fin


def get_game_finance(gameType: GameType, _date=None):
    if _date is None:
        _date = datetime.now()
    if (
        not Finance.objects.filter(deleted=False)
        .filter(createdAt__year=_date.year)
        .filter(createdAt__month=_date.month)
        .filter(createdAt__day=_date.day)
        .filter(finance_type=FinanceType.game.value)
        .filter(game_type=gameType.value)
        .exists()
    ):
        Finance.objects.create(
            finance_type=FinanceType.game.value,
            createdAt=_date,
            game_type=gameType.value,
        )

    f = (
        Finance.objects.filter(deleted=False)
        .filter(createdAt__year=_date.year)
        .filter(createdAt__month=_date.month)
        .filter(createdAt__day=_date.day)
        .filter(finance_type=FinanceType.game.value)
        .filter(game_type=gameType.value)
        .select_for_update()
        .first()
    )
    return f


def get_wxuser_recharge_withdraw_finance(
    user_uuid, _date=None, raffle_cost_type=FinanceRechargeRaffleCostType.none
):
    if _date is None:
        _date = datetime.now()
    uuid_list = get_web_settings_statistical_exclude_user_uuid_list()
    status = FinanceStatus.user
    _user_uuid = user_uuid
    if _user_uuid is not None:
        if isinstance(_user_uuid, str):
            if _user_uuid != "":
                _user_uuid = uuid.UUID(_user_uuid)

        if _user_uuid in uuid_list:
            status = FinanceStatus.proxy

    if (
        not Finance.objects.filter(deleted=False)
        .filter(createdAt__year=_date.year)
        .filter(createdAt__month=_date.month)
        .filter(createdAt__day=_date.day)
        .filter(finance_type=FinanceType.wxuser.value)
        .filter(raffle_cost_type=raffle_cost_type.value)
        .filter(game_type=0)  # 这里设置 作为一个只统计充值与提现
        .filter(user_uuid=user_uuid)
        .filter(finance_status=status)
        .exists()
    ):
        Finance.objects.create(
            user_uuid=user_uuid,
            raffle_cost_type=raffle_cost_type.value,
            finance_type=FinanceType.wxuser.value,
            game_type=0,  # 这里设置 作为一个只统计充值与提现
            finance_status=status,
            createdAt=_date,
        )

    f = (
        Finance.objects.filter(deleted=False)
        .filter(createdAt__year=_date.year)
        .filter(createdAt__month=_date.month)
        .filter(createdAt__day=_date.day)
        .filter(finance_type=FinanceType.wxuser.value)
        .filter(raffle_cost_type=raffle_cost_type.value)
        .filter(game_type=0)  # 这里设置 作为一个只统计充值与提现
        .filter(user_uuid=user_uuid)
        .filter(finance_status=status)
        .select_for_update()
        .first()
    )
    return f


def get_wxuser_finance(gameType: GameType, user_uuid, game_uuid, _date=None):
    if _date is None:
        _date = datetime.now()

    uuid_list = get_web_settings_statistical_exclude_user_uuid_list()
    status = FinanceStatus.user
    _user_uuid = user_uuid
    if _user_uuid is not None:
        if isinstance(_user_uuid, str):
            if _user_uuid != "":
                _user_uuid = uuid.UUID(_user_uuid)

        if _user_uuid in uuid_list:
            status = FinanceStatus.proxy
    if (
        not Finance.objects.filter(deleted=False)
        .filter(createdAt__year=_date.year)
        .filter(createdAt__month=_date.month)
        .filter(createdAt__day=_date.day)
        .filter(finance_type=FinanceType.wxuser.value)
        .filter(game_type=gameType.value)
        .filter(user_uuid=user_uuid)
        .filter(game_uuid=game_uuid)
        .filter(finance_status=status)
        .exists()
    ):
        Finance.objects.create(
            finance_type=FinanceType.wxuser.value,
            game_type=gameType.value,
            user_uuid=user_uuid,
            game_uuid=game_uuid,
            createdAt=_date,
            finance_status=status,
        )

    f = (
        Finance.objects.filter(deleted=False)
        .filter(createdAt__year=_date.year)
        .filter(createdAt__month=_date.month)
        .filter(createdAt__day=_date.day)
        .filter(finance_type=FinanceType.wxuser.value)
        .filter(game_type=gameType.value)
        .filter(user_uuid=user_uuid)
        .filter(game_uuid=game_uuid)
        .filter(finance_status=status)
        .select_for_update()
        .first()
    )

    return f


class UserWithdraw(BaseModel):
    # 操作的管理员
    admin_uuid = models.UUIDField()
    # 提现用户
    user_uuid = models.UUIDField()
    old_hunjing = models.PositiveIntegerField()
    new_hunjing = models.PositiveIntegerField()

    # 提现金额
    withdraw_money = models.PositiveIntegerField(default=0)

    class Meta:
        db_table = "UserWithdraw"  # 数据库表名
        indexes = [
            models.Index(fields=["uuid"]),
            models.Index(fields=["deleted"]),
            models.Index(fields=["admin_uuid"]),
            models.Index(fields=["user_uuid"]),
        ]
        ordering = ["-createdAt"]


@unique
class ModifyType(Enum):
    stored_money = 1
    hunjing = 2
    score = 3


def admin_modify_user_value(
    admin: JuqiAdmin, user: Users, modify_type, modify_value, modify_detail
):
    """
    管理员变更操作
    Args:
        admin: 管理员uuid
        user: 用户uuid
        modify_type: 变更类型
        modify_value: 变更值
        modify_detail: 变更细节
    Returns:

    """

    if modify_type == ModifyType.stored_money:
        _old_value = user.stored_money
        _new_value = user.stored_money + modify_value
        user.stored_money = _new_value

        if _new_value < 0:  # 检查是否扣除了不存在的部分
            raise ValueError

        _record = {
            "user_uuid": user.uuid,
            "stored_money": modify_value,
            "old_stored_money": _old_value,
            "new_stored_money": _new_value,
            "detail": modify_detail,
        }
        UserStoredMoneyRecord.objects.create(**_record)

    elif modify_type == ModifyType.hunjing:
        _old_value = user.hunjing
        _new_value = user.hunjing + modify_value
        user.hunjing = _new_value

        _record = {
            "user_uuid": user.uuid,
            "hunjing": modify_value,
            "old_hunjing": _old_value,
            "new_hunjing": _new_value,
            "detail": modify_detail,
        }
        UserHunJingRecord.objects.create(**_record)

    elif modify_type == ModifyType.score:
        _old_value = user.score
        _new_value = user.score + modify_value
        user.score = _new_value

        _record = {
            "user_uuid": user.uuid,
            "score": modify_value,
            "old_score": _old_value,
            "new_score": _new_value,
            "detail": modify_detail,
            "manager": admin.user,
        }
        UserScoreRecord.objects.create(**_record)


@unique
class GameRuleType(models.IntegerChoices):
    system = 0  # 系统
    game = 1  # 游戏


class GameRule(BaseModel):
    key = models.CharField(max_length=200, verbose_name="键值", unique=True)

    body = models.TextField(verbose_name="规则内容")

    type = models.PositiveIntegerField(
        verbose_name="规则类型", default=GameRuleType.system, choices=GameRuleType.choices
    )

    class Meta:
        db_table = "GameRule"  # 数据库表名
        indexes = [
            models.Index(fields=["uuid"]),
            models.Index(fields=["deleted"]),
            models.Index(fields=["createdAt"]),
            models.Index(fields=["key"]),
            models.Index(fields=["type"]),
        ]
